using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace DebugConsole.Components
{
    /// <summary>
    /// Shows important alerts on the screen.
    /// </summary>
    public class Alerter : DebugComponent
    {
        private LinkedList<DebugItem> alerts = new LinkedList<DebugItem>();
        private Vector2 alertPosition;
        private SpriteBatch spriteBatch;

        /// <summary>
        /// We use this list to delete elements that are not
        /// being shown anymore.
        /// </summary>
        LinkedList<DebugItem> toRemove = new LinkedList<DebugItem>();

        #region Constructors
        public Alerter(DebugSharedResources resources) : base(resources)
        {
            this.alertPosition = new Vector2(resources.device.Viewport.Width / 2 - 100, resources.device.Viewport.Height / 2 - 100);
            this.spriteBatch = resources.spriteBatch;
            HandleCommand("alert");
        }
        #endregion


        #region Execute
        public override void Execute(string[] command, params object[] arguments)
        {
            StringBuilder value = new StringBuilder();
            // We need at least the command, and something to alert about.
            if (command.Length < 2)
            {
                return;
            }

            for (int i = 1; i < command.Length; i++)
            {
                value.Append(command[i]);
            }

            alert(value.ToString());
        }
        #endregion


        #region Alerts
        public void alert(Object message)
        {
            alerts.AddLast(new DebugItem(message, alertPosition, 40));
            this.alertPosition.Y += 48;
            if (this.alertPosition.Y >= 300) this.alertPosition.Y = 150;
        }
        #endregion

        #region Update
        public override void Update(Microsoft.Xna.Framework.GameTime gameTime)
        {
            foreach (DebugItem i in alerts)
            {
                if (i.remainingTime > 0) i.remainingTime--;
                else if (i.remainingTime == 0) toRemove.AddLast(i);
            }
            foreach (DebugItem i in toRemove)
            {
                alerts.Remove(i);
            }
            toRemove.Clear();
            base.Update(gameTime);
        }
        #endregion

        #region Draw
        public override void  Draw(GameTime gameTime)
        {
            spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.None);
            foreach (DebugItem i in alerts)
            {
                Color forecolor = new Color(255, 255, 255, (byte)MathHelper.Clamp((i.remainingTime / 30f) * 255, 0, 255));
                Color backcolor = new Color(0, 0, 0, (byte)MathHelper.Clamp((i.remainingTime / 60f) * 255, 0, 255));
                spriteBatch.DrawString(Resources.fontAlert, ((DebugItem)i).value.ToString(), ((DebugItem)i).position + new Vector2(-2, 2), backcolor);
                spriteBatch.DrawString(Resources.fontAlert, ((DebugItem)i).value.ToString(), ((DebugItem)i).position, forecolor);
            }
            spriteBatch.End();
        }
        #endregion
    }
}
